package com.wonderland.lucy.security.shiro;

import com.wonderland.lucy.jedis.JedisTempalte;
import com.wonderland.lucy.util.SerializeUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

import java.io.Serializable;
import java.util.Collection;

/**
 * Created by gaoxy on 2015-11-25 0025.
 */
public class JedisSessionDao extends AbstractSessionDAO {
    private final static Logger logger = LoggerFactory.getLogger(JedisSessionDao.class);

    public static final String KEY_PREFIX = "shiro_redis_session:";

    private String keyPrefix = KEY_PREFIX;

    public void setKeyPrefix(String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    private JedisTempalte jedisTempalte;

    public void setJedisTempalte(JedisTempalte jedisTempalte) {
        this.jedisTempalte = jedisTempalte;
    }

    @Override
    protected Serializable doCreate(final Session session) {
        final Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        saveSession(session);
        return sessionId;
    }

    private void saveSession(final Session session) {
        final byte[] key = getByteKey(session.getId());
        final byte[] value = SerializeUtils.serialize(session);
        jedisTempalte.execute(jedis -> {
            jedis.set(key, value);
            jedis.expire(key, (int) session.getTimeout() / 1000);
        });
    }


    @Override
    protected Session doReadSession(final Serializable sessionId) {
        if(sessionId == null){
            logger.error("session id is null");
            return null;
        }
        byte[] sessionBytes = jedisTempalte.execute(jedis -> {
            return jedis.get(getByteKey(sessionId));
        });
        return (Session)SerializeUtils.deserialize(sessionBytes);
    }

    public void update(Session session) throws UnknownSessionException {
        saveSession(session);
    }

    public void delete(final Session session) {
        if (session == null || session.getId() == null) {
            logger.error("session or session id is null");
            return;
        }
        jedisTempalte.execute(jedis -> {
            jedis.del(getByteKey(session.getId()));
        });
    }

    public Collection<Session> getActiveSessions() {
        return null;
    }

    /**
     * 获得byte[]型的key
     *
     * @param sessionId
     * @return
     */
    private byte[] getByteKey(Serializable sessionId) {
        String preKey = this.keyPrefix + sessionId;
        return preKey.getBytes();
    }
}
